Java 排序之插入排序、希尔排序
今天学习了一下 Java 数组的相关操作,包含排序和查找,现在先将排序记录巩固一下。
常用并且比较重要的几种排序:插入排序、希尔排序、快速排序、归并排序、冒泡排序、选择排序。
一、插入排序
1. 插入排序算法思想
1) 普遍思想
插入排序的算法是一种简单直观的排序算法。它的工作原理是通过构建有序序列,对于未排序的数据,在已排序的序列中从后向前扫描,找到相应位置并插入。插入排序在实现上,在从后向前扫描过程中,需要反复把已排序元素逐步向后挪位,为最新元素提供插入空间。
2) 我的理解与分析
我最初看到上面的思想,就是一脸懵逼,读都读不懂,又去找了很多资料,才能理解那么一点点,所以这里用通俗一点的话来解释:
假设有一个数组:
int[] arr = { 22, 11, 10, 55, 44 };
第 0 个元素
22
看作已经排好序;取出第 1 个元素
11
,在已经排序的元素序列中(第一步的22
)从后向前扫描;如果新元素
11
比已排序的元素22
小,就把22
往后挪,并将11
插入到前面。这个时候数组应该如下:int[] arr = { 11, 22, 10, 55, 44 }
接着在取出第 2 个元素
10
,与第一个元素22
相比,如果比第一个元素小,就插入到22
之前。这个时候数组应该如下:int[] arr = { 11, 10, 22, 55, 44 }
10
插入后继续与前面的元素相比,小则插入,大则不动。这个时候数组应该如下:int[] arr = { 10, 11, 22, 55, 44 }
取出第 3 个元素继续比较……
插入排序的特点:越有序,操作的次数越少,效率越高。
2. 算法图解附视频
视频 点此查看。
3. 算法代码
import java.util.Arrays;
public class InsertSort {
public static void main(String[] args) {
int[] arr = { 11, 22, 10, 55, 44 };
sort(arr);
System.out.println(Arrays.toString(arr));
}
public static void sort(int[] arr) {
for (int i = 1; i < arr.length; i++) { // 从第一个元素开始遍历
for (int j = i; (j > 0) && (arr[j] < arr[j - 1]); j--) { // 条件:是否比前一个元素小,j-- 是为了挪位后再次与前一个元素比较
int temp = arr[j]; // 把移动的元素暂时存起来
arr[j] = arr[j - 1]; // 把大的元素往后挪
arr[j - 1] = temp; // 把小的元素放到前面
}
}
}
}
二、希尔排序
1. 算法简介
希尔排序 是插入排序的改进版本。为什么是插入排序的改进版本呢?上面说过的插入排序,它是取出一个元素然后从后向前比较,如果小于就放到前面来,并且它的特点是 越有序,效率越高。对于插入排序,序列数据少的话还行,要是序列数据特别多,并且是无序,那么插入排序的效率就会很慢,所以就出现了一个希尔排序,使序列更 接近有序,这样的话,相对于插入排序操作数据较大的时候要快一点,不过它最终属于插入排序类中。
2. 算法分析
希尔排序,先将要排序的一组数据按某个增量 d(n/2,n 为排序数的个数) 分成若干组(把相隔 d 的数据分为一组),并在各组内进行直接插入排序,然后再用一个较小的增量 (d/2) 对它进行分组,在每组中再进行插入排序,当增量减到 1 时,进行插入排序后,排序完成。
假设有一个数组:
int[] arr = { 49, 38, 65, 97, 76, 13, 27, 49, 55, 04 };
先取一个增量 d = n/2 = 5,把每相隔 5 的数据分为一组,如下:
第一组 ---> 49 -- 13 第二组 ---> 38 -- 27 第三组 ---> 65 -- 49 第四组 ---> 97 -- 55 第五组 ---> 76 -- 04
每一组进行插入排序,如下:
第一组 ---> 13 -- 49 第二组 ---> 27 -- 38 第三组 ---> 49 -- 65 第四组 ---> 55 -- 97 第五组 ---> 04 -- 76
第一次的结果为:
{ 13, 27, 49, 55, 04, 49, 38, 65, 97, 76 };
取第二个增量 d2 = d/2 = 3,把每相隔 3 的数据分为一组,如下:
第一组 ---> 13 -- 55 -- 38 -- 76 第二组 ---> 27 -- 04 -- 65 第三组 ---> 49 -- 49 -- 97
每一组进行插入排序,如下:
第一组 ---> 13 -- 38 -- 55 -- 76 第二组 ---> 04 -- 27 -- 65 第三组 ---> 49 -- 49 -- 97
第二次的结果为:
{ 13, 04, 49, 38, 27, 49, 55, 65, 97, 76 };
取第三个增量 d3 = d2/2 = 1,把每相隔 1 的数据分为一组,这时开始直接插入排序即可,结果如下:
{ 04, 13, 27, 38, 49, 49, 55, 65, 76, 97 };
增量 d 取值为奇数。
3. 算法图解附视频
视频 点此查看。
4. 算法代码
import java.util.Arrays;
public class ShellSort {
public static void main(String[] args) {
int[] arr = { 49, 38, 65, 97, 76, 13, 27, 49, 55, 04 };
sort(arr);
System.out.println(Arrays.toString(arr));
}
public static void sort(int[] arr) {
for (int d = arr.length / 2; d > 2; d /= 2) {
for (int i = 0; i < d; i++) {
insertSort(arr, i, d);
}
}
insertSort(arr, 0, 1);
}
// 插入排序
public static void insertSort(int[] arr, int i, int d) {
for (int a = i + d; a < arr.length; a += d) { // a += d
for (int j = a; (j >= d) && (arr[j] < arr[j - d]); j -= d) {
int temp = arr[j];
arr[j] = arr[j - d];
arr[j - d] = temp;
}
}
}
}
转载请注明来源,欢迎对文章中的引用来源进行考证,欢迎指出任何有错误或不够清晰的表达。可以在下面评论区评论,也可以加QQ(2602138376)
文章标题:Java 排序之插入排序、希尔排序
文章字数:1.4k
本文作者:Zevs
发布时间:2019-08-26, 10:43:53
最后更新:2019-08-26, 08:11:28
原始链接:http://zhsh666.xyz/2019/08/26/Java 排序之插入排序、希尔排序/版权声明: "署名-非商用-相同方式共享 4.0" 转载请保留原文链接及作者。
√本站访问人数:人次 | ◎本站总访问量:
次